#include "modeltodraw.h"
#include <QDebug>
#include <QString>
#include "coldet.h"


double mymatrix[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -8, 1};

ModelToDraw::ModelToDraw(char *model_name, double scale)
{
    this->scale = scale;
    model = new object3ds;
    loadModel(model_name, model);
    collisionmodel = newCollisionModel3D(true);
    forCollision(collisionmodel, model, scale);
    special = new double[16];
    for(int i = 0; i < 16; i++){
        special[i] = mymatrix[i];
    }
}


ModelToDraw::~ModelToDraw()
{
    collisionmodel->~CollisionModel3D();
    if(model->model != NULL){
        lib3ds_file_free(model->model);
    }
    free(model);
}


/**********************
 * Loads the elements of a 3DS model
 */
void ModelToDraw::loadModel(char *name, object3ds *modelling)
{
    modelling->model = lib3ds_file_open(name);
    if(!modelling->model){
        qDebug("Model %f did not load", name);
    } else {
        modelling->mesh = modelling->model->meshes;
        modelling->material= modelling->model->materials;
        modelling->camera= modelling->model->cameras;
        modelling->light= modelling->model->lights;
        getfaces(modelling);
    }
}
// end loadModel()

/**********************
 * Scales a vector
 */
void ModelToDraw::scaleIt(float *toscale, float scalex, float scaley, float scalez)
{
    toscale[0] = toscale[0]*scalex;
    toscale[1] = toscale[1]*scaley;
    toscale[2] = toscale[2]*scalez;
} // end scaleIt()


/**********************
 * Copies elements of a float array representing a vector
 */
void ModelToDraw::copyArray(float *source, float *destination, int howmany)
{
    for(int i = 0; i < howmany; i++){
        destination[i] = source[i];
    }
}
// end copyArray()


/**********************
 * Loads all triangles from the model, and scales it
 */
void ModelToDraw::forCollision(CollisionModel3D *toaddto, object3ds *todraw, float scaleFactor)
{
    long meshcount;
    for(meshcount=0;meshcount<todraw->model->nmeshes;meshcount++)
    {
        todraw->face=todraw->mesh[meshcount]->faces;
        for(long i=0;i<todraw->mesh[meshcount]->nfaces;i++)
        {
            float a[3];
            float b[3];
            float c[3];
            copyArray(todraw->mesh[meshcount]->vertices[todraw->face[i].index[0]], a, 3);
            copyArray(todraw->mesh[meshcount]->vertices[todraw->face[i].index[1]], b, 3);
            copyArray(todraw->mesh[meshcount]->vertices[todraw->face[i].index[2]], c, 3);
            scaleIt(a, scaleFactor,scaleFactor,scaleFactor);
            scaleIt(b, scaleFactor,scaleFactor,scaleFactor);
            scaleIt(c, scaleFactor,scaleFactor,scaleFactor);
            toaddto->addTriangle(a, b, c);
        }
    }
    toaddto->finalize();
}
// end forCollision()

void ModelToDraw::getfaces(object3ds *todraw)
{
    todraw->total_face=0;
    for(long meshcount=0;meshcount<todraw->model->nmeshes;meshcount++)
    {
        todraw->total_face+=todraw->mesh[meshcount]->nfaces;
    }
}

void ModelToDraw::updateCollisionModel(double scale)
{
    collisionmodel->~CollisionModel3D(); //destroy model
    collisionmodel = newCollisionModel3D(true); //make new one
    forCollision (collisionmodel, model, scale);
}

void ModelToDraw::setXYZ(double x, double y, double z)
{
    special[12] = x;
    special[13] = y;
    special[14] = z;
}

double *ModelToDraw::getMatrix()
{
    return special;
}

void ModelToDraw::setMatrix(double *toset)
{
    for(int i = 0; i < 16; i ++){
        special[i] = toset[i];
    }
}
